home *** CD-ROM | disk | FTP | other *** search
- <h1>Extension Classes, Python Extension Types Become Classes</h1>
- <p> Jim Fulton, Digital Creations, Inc.
- jim@digicool.com</p>
-
- <p> <a href="COPYRIGHT.html">Copyright (C) 1996-1998, Digital Creations</a>.</p>
-
- <h2>Abstract</h2>
- <p> A lightweight mechanism has been developed for making Python
- extension types more class-like. Classes can be developed in an
- extension language, such as C or C++, and these classes can be
- treated like other python classes:</p>
-
- <ul><li><p>They can be sub-classed in python,</p>
-
-
- <li><p>They provide access to method documentation strings, and</p>
-
-
- <li><p>They can be used to directly create new instances.</p>
-
- </ul>
- <p> An example class shows how extension classes are implemented and how
- they differ from extension types.</p>
-
- <p> Extension classes provide additional extensions to class and
- instance semantics, including:</p>
-
- <ul><li><p>A protocol for accessing subobjects "in the context of" their
- containers. This is used to implement custom method types
- and <a href="Acquisition.html">environmental acquisition</a>.</p>
-
-
- <li><p>A protocol for overriding method call semantics. This is used
- to implement "synchonized" classes and could be used to
- implement argument type checking.</p>
-
-
- <li><p>A protocol for class initialization that supports execution of a
- special <code>__class_init__</code> method after a class has been
- initialized.</p>
-
- </ul>
- <p> Extension classes illustrate how the Python class mechanism can be
- extended and may provide a basis for improved or specialized class
- models. </p>
-
-
- <h2>Releases</h2>
- <p> To find out what's changed in this release,
- see the <a href="release.html">release notes</a>.</p>
-
-
- <h2>Problem</h2>
- <p> Currently, Python provides two ways of defining new kinds of objects:</p>
-
- <ul><li><p>Python classes</p>
-
-
- <li><p>Extension types</p>
-
- </ul>
- <p> Each approach has it's strengths. Extension types provide much greater
- control to the programmer and, generally, better performance. Because
- extension types are written in C, the programmer has greater access to
- external resources. (Note that Python's use of the term type has
- little to do with the notion of type as a formal specification.)</p>
-
- <p> Classes provide a higher level of abstraction and are generally much
- easier to develop. Classes provide full inheritance support, while
- support for inheritance when developing extension types is very
- limited. Classes provide run-time meta-data, such as method documentation
- strings, that are useful for documentation and discovery. Classes
- act as factories for creating instances, while separate functions
- must be provided to create instances of types.</p>
-
- <p> It would be useful to combine the features of the two approaches. It
- would be useful to be able to have better support for inheritance for
- types, or to be able to subclass from types in Python. It would be
- useful to be able to have class-like meta-data support for types and
- the ability to construct instances directly from types.</p>
-
- <p> Our software is developed in Python. When necessary, we convert
- debugged Python routines and classes to C for improved
- performance. In most cases, a small number of methods in a class
- is responsible for most of the computation. It should be possible
- to convert only these methods to C, while leaving the other method
- in Python. A natural way to approach this is to create a base
- class in C that contains only the performance-critical aspects of
- a class' implementation and mix this base class into a Python
- class. </p>
-
- <p> We have need, in a number of projects, for semantics that are
- slightly different than the usual class and instance semantics,
- yet we don't want to do most of our development in C. For
- example, we have developed a persistence mechanism <a href="#1">[1]</a> that
- redefines <code>__getattr__</code> and <code>__setattr__</code> to take storage-related
- actions when object state is accessed or modified. We want to be
- able to take certain actions on <em>every</em> attribute reference, but
- for python class instances, <code>__getattr__</code> is only called when
- attribute lookup fails by normal means.</p>
-
- <p> As another example, we would like to have greater control over how
- methods are bound. Currently, when accessing a class
- instance attribute, the attribute value is bound together with the
- instance in a method object <em>if and only if</em> the attribute value is a
- python function. For some applications, we might also want to be
- able to bind extension functions, or other types of callable
- objects, such as HTML document templates <a href="#2">[2]</a>. Furthermore,
- we might want to have greater control over how objects are bound.
- For example, we might want to bind instances and callable objects
- with special method objects that assure that no more than one thread
- accesses the object or method at one time.</p>
-
- <p> We can provide these special semantics in extension types, but we
- wish to provide them for classes developed in Python.</p>
-
-
- <h2>Background</h2>
- <p> At the first Python Workshop, Don Beaudry presented work <a href="#3">[3]</a> done
- at V.I. Corp to integrate Python with C++ frameworks. This system
- provided a number of important features, including:</p>
-
- <ul><li><p>Definition of extension types that provide class-like meta-data
- and that can be called to create instances.</p>
-
-
- <li><p>Ability to subclass in python from C types.</p>
-
-
- <li><p>Ability to define classes in python who's data are stored as
- C structures rather than in dictionaries to better interface to
- C and C++ libraries, and for better performance.</p>
-
-
- <li><p>Less dynamic data structures. In particular, the data structure
- for a class is declared during class definition.</p>
-
-
- <li><p>Support for enumeration types.</p>
-
- </ul>
- <p> This work was not released, initially.</p>
-
- <p> Shortly after the workshop, changes were made to Python to support
- the sub-classing features described in <a href="#3">[3]</a>. These changes were not
- documented until the fourth Python Workshop <a href="#4">[4]</a>.</p>
-
- <p> At the third Python workshop, I presented some work I had done on
- generating module documentation for extension types. Based on the
- discussion at this workshop, I developed a meta-type proposal <a href="#5">[5]</a>.
- This meta-type proposal was for an object that simply stored
- meta-information for a type, for the purpose of generating module
- documentation.</p>
-
- <p> In the summer of 1996, Don Beaudry released the system described in
- <a href="#3">[3]</a> under the name MESS <a href="#6">[6]</a>. MESS addresses a number of needs but
- has a few drawbacks:</p>
-
- <ul><li><p>Only single inheritance is supported.</p>
-
-
- <li><p>The mechanisms for defining MESS extension types is very different
- from and more complicated than the standard Python type creation
- mechanism.</p>
-
-
- <li><p>Defining MESS types requires the use of an extensive C
- applications programming interface. This presents problems for
- configuring dynamically-loaded extension modules unless the MESS
- library is linked into the Python interpreter.</p>
-
-
- <li><p>Because the system tries to do a number of different things, it is
- fairly large, about 15,000 lines.</p>
-
-
- <li><p>There is very little documentation, especially for the C
- programming interface.</p>
-
-
- <li><p>The system is a work in progress, with a number of outstanding
- bugs.</p>
-
- </ul>
- <p> As MESS matures, we expect most of these problems to be addressed.</p>
-
-
- <h2>Extension Classes</h2>
- <p> To meet short term needs for a C-based persistence mechanism <a href="#1">[1]</a>, an
- extension class module was developed using the mechanism described
- in <a href="#4">[4]</a> and building on ideas from MESS <a href="#6">[6]</a>. The extension class module
- recasts extension types as "extension classes" by seeking to
- eliminate, or at least reduce semantic differences between types and
- classes. The module was designed to meet the following goal:</p>
-
- <ul><li><p>Provide class-like behavior for extension types, including
- interfaces for meta information and for constructing instances.</p>
-
-
- <li><p>Support sub-classing in Python from extension classes, with support
- for multiple inheritance.</p>
-
-
- <li><p>Provide a small hardened implementation that can be used for
- current products.</p>
-
-
- <li><p>Provide a mechanism that requires minimal modification to existing
- extension types.</p>
-
-
- <li><p>Provide a basis for research on alternative semantics for classes
- and inheritance.</p>
-
- </ul>
- <p> <strong>Note:</strong> I use <em>non-standard</em> terminology here. By standard
- <em>python</em> terminology, only standard python classes can be called
- classes. ExtensionClass "classes" are technically just "types"
- that happen to swim, walk and quack like python classes.</p>
-
- <h3>Base extension classes and extension subclasses</h3>
- <p> Base extension classes are implemented in C. Extension subclasses
- are implemented in Python and inherit, directly or indirectly from
- one or more base extension classes. An extension subclass may
- inherit from base extension classes, extension subclasses, and
- ordinary python classes. The usual inheritance order rules
- apply. Currently, extension subclasses must conform to the
- following two rules:</p>
-
- <ul><li><p>The first super class listed in the class statement defining an
- extension subclass must be either a base extension class or an
- extension subclass. This restriction will be removed in
- Python-1.5.</p>
-
-
- <li><p>At most one base extension direct or indirect super class may
- define C data members. If an extension subclass inherits from
- multiple base extension classes, then all but one must be mix-in
- classes that provide extension methods but no data.</p>
-
- </ul>
-
- <h3>Meta Information</h3>
- <p> Like standard python classes, extension classes have the following
- attributes containing meta-data:</p>
-
- <dl><dt> <code>__doc__</code> <dd><p>a documentation string for the class,</p>
-
-
- <dt> <code>__name__</code> <dd><p>the class name,</p>
-
-
- <dt> <code>__bases__</code><dd><p>a sequence of base classes,</p>
-
-
- <dt> <code>__dict__</code> <dd><p>a class dictionary, and</p>
-
-
- <dt> <code>__module__</code><dd><p>the name of the module in which the class was
- defined. </p>
-
- </dl>
- <p> The class dictionary provides access to unbound methods and their
- documentation strings, including extension methods and special
- methods, such as methods that implement sequence and numeric
- protocols. Unbound methods can be called with instance first
- arguments.</p>
-
-
- <h3>Subclass instance data</h3>
- <p> Extension subclass instances have instance dictionaries, just
- like Python class instances do. When fetching attribute values,
- extension class instances will first try to obtain data from the
- base extension class data structure, then from the instance
- dictionary, then from the class dictionary, and finally from base
- classes. When setting attributes, extension classes first attempt
- to use extension base class attribute setting operations, and if
- these fail, then data are placed in the instance dictionary.</p>
-
-
-
- <h2>Implementing base extension classes</h2>
- <p> A base extension class is implemented in much the same way that an
- extension type is implemented, except:</p>
-
- <ul><li><p>The include file, <code>ExtensionClass.h</code>, must be included.</p>
-
-
- <li><p>The type structure is declared to be of type <code>PyExtensionClass</code>, rather
- than of type <code>PyTypeObject</code>.</p>
-
-
- <li><p>The type structure has an additional member that must be defined
- after the documentation string. This extra member is a method chain
- (<code>PyMethodChain</code>) containing a linked list of method definition
- (<code>PyMethodDef</code>) lists. Method chains can be used to implement
- method inheritance in C. Most extensions don't use method chains,
- but simply define method lists, which are null-terminated arrays
- of method definitions. A macro, <code>METHOD_CHAIN</code> is defined in
- <code>ExtensionClass.h</code> that converts a method list to a method chain.
- (See the example below.)</p>
-
-
- <li><p>Module functions that create new instances must be replaced by
- <code>__init__</code> methods that initialize, but does not create storage for
- instances.</p>
-
-
- <li><p>The extension class must be initialized and exported to the module
- with::</p>
- <PRE>
- PyExtensionClass_Export(d,"name",type);
-
- where 'name' is the module name and 'type' is the extension class
- type object.
-
- </PRE>
-
- </ul>
- <h3>Attribute lookup</h3>
- <p> Attribute lookup is performed by calling the base extension class
- <code>getattr</code> operation for the base extension class that includes C
- data, or for the first base extension class, if none of the base
- extension classes include C data. <code>ExtensionClass.h</code> defines a
- macro <code>Py_FindAttrString</code> that can be used to find an object's
- attributes that are stored in the object's instance dictionary or
- in the object's class or base classes:</p>
- <PRE>
- v = Py_FindAttrString(self,name);
-
- </PRE>
-
- <p> where <code>name</code> is a C string containing the attribute name.</p>
-
- <p> In addition, a macro is provided that replaces <code>Py_FindMethod</code>
- calls with logic to perform the same sort of lookup that is
- provided by <code>Py_FindAttrString</code>.</p>
-
- <p> If an attribute name is contained in a Python string object,
- rather than a C string object, then the macro <code>Py_FindAttr</code> should
- be used to look up an attribute value.</p>
-
-
- <h3>Linking</h3>
- <p> The extension class mechanism was designed to be useful with
- dynamically linked extension modules. Modules that implement
- extension classes do not have to be linked against an extension
- class library. The macro <code>PyExtensionClass_Export</code> imports the
- <code>ExtensionClass</code> module and uses objects imported from this module
- to initialize an extension class with necessary behavior.</p>
-
-
- <h3>Example: MultiMapping objects</h3>
- <p> An <a href="MultiMapping.html">example</a> is provided that illustrates the
- changes needed to convert an existing type to an ExtensionClass.</p>
-
-
-
- <h2>Implementing base extension class constructors</h2>
- <p> Some care should be taken when implementing or overriding base
- class constructors. When a Python class overrides a base class
- constructor and fails to call the base class constructor, a
- program using the class may fail, but it will not crash the
- interpreter. On the other hand, an extension subclass that
- overrides a constructor in an extension base class must call the
- extension base class constructor or risk crashing the interpreter.
- This is because the base class constructor may set C pointers that,
- if not set properly, will cause the interpreter to crash when
- accessed. This is the case with the <code>MultiMapping</code> extension base
- class shown in the example above.</p>
-
- <p> If no base class constructor is provided, extension class instance
- memory will be initialized to 0. It is a good idea to design
- extension base classes so that instance methods check for
- uninitialized memory and perform initialialization if necessary.
- This was not done above to simplify the example.</p>
-
-
- <h2>Overriding methods inherited from Python base classes</h2>
- <p> A problem occurs when trying to overide methods inherited from
- Python base classes. Consider the following example:</p>
- <PRE>
- from ExtensionClass import Base
-
- class Spam:
-
- def __init__(self, name):
- self.name=name
-
- class ECSpam(Base, Spam):
-
- def __init__(self, name, favorite_color):
- Spam.__init__(self,name)
- self.favorite_color=favorite_color
-
- </PRE>
-
- <p> This implementation will fail when an <code>ECSpam</code> object is
- instantiated. The problem is that <code>ECSpam.__init__</code> calls
- <code>Spam.__init__</code>, and <code>Spam.__init__</code> can only be called with a
- Python instance (an object of type <code>"instance"</code>) as the first
- argument. The first argument passed to <code>Spam.__init__</code> will be an
- <code>ECSpam</code> instance (an object of type <code>ECSPam</code>).</p>
-
- <p> To overcome this problem, extension classes provide a class method
- <code>inheritedAttribute</code> that can be used to obtain an inherited
- attribute that is suitable for calling with an extension class
- instance. Using the <code>inheritedAttribute</code> method, the above
- example can be rewritten as:</p>
- <PRE>
- from ExtensionClass import Base
-
- class Spam:
-
- def __init__(self, name):
- self.name=name
-
- class ECSpam(Base, Spam):
-
- def __init__(self, name, favorite_color):
- ECSpam.inheritedAttribute('__init__')(self,name)
- self.favorite_color=favorite_color
-
- </PRE>
-
- <p> This isn't as pretty but does provide the desired result.</p>
-
-
- <h2>New class and instance semantics</h2>
- <h3>Context Wrapping</h3>
- <p> It is sometimes useful to be able to wrap up an object together
- with a containing object. I call this "context wrapping"
- because an object is accessed in the context of the object it is
- accessed through.</p>
-
- <p> We have found many applications for this, including:</p>
- <ul><li><p>User-defined method objects,</p>
-
-
- <li><p><a href="Acquisition.html">Acquisition</a> and</p>
-
-
- <li><p>Computed attributes</p>
-
- </ul>
-
- <h4>User-defined method objects</h4>
- <p> Python classes wrap Python function attributes into methods. When a
- class has a function attribute that is accessed as an instance
- attribute, a method object is created and returned that contains
- references to the original function and instance. When the method
- is called, the original function is called with the instance as the
- first argument followed by any arguments passed to the method.</p>
-
- <p> Extension classes provide a similar mechanism for attributes that
- are Python functions or inherited extension functions. In
- addition, if an extension class attribute is an instance of an
- extension class that defines an <code>__of__</code> method, then when the
- attribute is accessed through an instance, it's <code>__of__</code> method
- will be called to create a bound method.</p>
-
- <p> Consider the following example:</p>
- <PRE>
- import ExtensionClass
-
- class CustomMethod(ExtensionClass.Base):
-
- def __call__(self,ob):
- print 'a %s was called' % ob.__class__.__name__
-
- class wrapper:
-
- def __init__(self,m,o): self.meth, self.ob=m,o
-
- def __call__(self): self.meth(self.ob)
-
- def __of__(self,o): return self.wrapper(self,o)
-
- class bar(ExtensionClass.Base):
- hi=CustomMethod()
-
- x=bar()
- hi=x.hi()
-
- </PRE>
-
- <p> Note that <code>ExtensionClass.Base</code> is a base extension class that
- provides very basic ExtensionClass behavior. </p>
-
- <p> When run, this program outputs: <code>a bar was called</code>.</p>
-
-
- <h4>Computed Attributes</h4>
- <p> It is not uncommon to wish to expose information via the
- attribute interface without affecting implementation data
- structures. One can use a custom <code>__getattr__</code> method to
- implement computed attributes, however, this can be a bit
- cumbersome and can interfere with other uses of <code>__getattr__</code>,
- such as for persistence.</p>
-
- <p> The <code>__of__</code> protocol provides a convenient way to implement
- computed attributes. First, we define a ComputedAttribute
- class. a ComputedAttribute is constructed with a function to
- be used to compute an attribute, and calls the function when
- it's <code>__of__</code> method is called:</p>
- <p> import ExtensionClass</p>
-
- <p> class ComputedAttribute(ExtensionClass.Base):</p>
- <p> def __init__(self, func): self.func=func</p>
-
- <p> def __of__(self, parent): return self.func(parent)</p>
-
-
-
- <p> Then we can use this class to create computed attributes. In the
- example below, we create a computed attribute, <code>radius</code>:</p>
- <p> from math import sqrt</p>
-
- <p> class Point(ExtensionClass.Base):</p>
- <p> def __init__(self, x, y): self.x, self.y = x, y</p>
-
- <p> radius=ComputedAttribute(lambda self: sqrt(self.x**2+self.y**2))</p>
-
-
-
- <p> which we can use just like an ordinary attribute:</p>
- <p> p=Point(2,2)
- print p.radius</p>
-
-
-
-
- <h3>Overriding method calls</h3>
- <p> Normally, when a method is called, the function wrapped by the
- method is called directly by the method. In some cases, it is
- useful for user-defined logic to participate in the actual
- function call. Extension classes introduce a new protocol that
- provides extension classes greater control over how their
- methods are called. If an extension class defines a special
- method, <code>__call_method__</code>, then this method will be called to
- call the functions (or other callable object) wrapped by the
- method. The method. <code>__call_method__</code> should provide the same
- interface as provided by the Python builtin <code>apply</code> function.</p>
-
- <p> For example, consider the expression: <code>x.meth(arg1, arg2)</code>. The
- expression is evaluated by first computing a method object that
- wraps <code>x</code> and the attribute of <code>x</code> stored under the name <code>meth</code>.
- Assuming that <code>x</code> has a <code>__call_method__</code> method defined, then
- the <code>__call_method__</code> method of <code>x</code> will be called with two
- arguments, the attribute of <code>x</code> stored under the name <code>meth</code>,
- and a tuple containing <code>x</code>, <code>arg1</code>, and <code>arg2</code>.</p>
-
- <p> To see how this feature may be used, see the Python module,
- <code>Syn.py</code>, which is included in the ExtensionClass distribution.
- This module provides a mix-in class that provides Java-like
- "synchonized" classes that limit access to their methods to one
- thread at a time.</p>
-
- <p> An interesting application of this mechanism would be to
- implement interface checking on method calls.</p>
-
-
- <h3>Method attributes</h3>
- <p> Methods of ExtensionClass instances can have user-defined
- attributes, which are stored in their associated instances.</p>
-
- <p> For example:</p>
- <PRE>
- class C(ExtensionClass.Base):
-
- def get_secret(self):
- "Get a secret"
- ....
-
- c=C()
-
- c.f.__roles__=['Trusted People']
-
- print c.f.__roles__ # outputs ['Trusted People']
- print c.f__roles__ # outputs ['Trusted People']
-
- print C.f.__roles__ # fails, unbound method
-
- </PRE>
-
- <p> A bound method attribute is set by setting an attribute in it's
- instance with a name consisting of the concatination of the
- method's <code>__name__</code> attribute and the attribute name.
- Attributes cannot be set on unbound methods.</p>
-
-
- <h3>Class initialization</h3>
- <p> Normal Python class initialization is similar to but subtley
- different from instance initialization. An instance <code>__init__</code>
- function is called on an instance immediately <em>after</em> it is
- created. An instance <code>__init__</code> function can use instance
- information, like it's class and can pass the instance to other
- functions. On the other hand, the code in class statements is
- executed immediately <em>before</em> the class is created. This means
- that the code in a class statement cannot use class attributes,
- like <code>__bases__</code>, or pass the class to functions.</p>
-
- <p> Extension classes provide a mechanism for specifying code to be
- run <em>after</em> a class has been created. If a class or one of it's
- base classes defines a <code>__class_init__</code> method, then this method
- will be called just after a class has been created. The one
- argument passed to the method will be the class, <em>not</em> an
- instance of the class.</p>
-
-
-
- <h2>Useful macros defined in ExtensionClass.h</h2>
- <p> A number of useful macros are defined in ExtensionClass.h.
- These are documented in <code>ExtensionClass.h</code>.</p>
-
-
- <h2>Pickleability</h2>
- <p> Classes created with ExtensionClass, including extension base
- classes are automatically pickleable. The usual gymnastics
- necessary to pickle <code>non-standard</code> types are not necessray for
- types that have been modified to be extension base classes.</p>
-
-
- <h2>Status</h2>
- <p> The current release of the extension class module is <a href="http://www.digicool.com/releases/ExtensionClass/ExtensionClass-1.1.tar.gz">1.1</a>.
- The core implementation has less than four thousand lines of code,
- including comments. This release requires Python 1.4 or higher.</p>
-
- <p> To find out what's changed in this release, see the
- <a href="release.html">release notes</a>.</p>
-
- <p> <a href="Installation.html">Installation instructions</a> are provided.</p>
-
-
- <h2>Issues</h2>
- <p> There are a number of issues that came up in the course of this work
- and that deserve mention.</p>
-
- <ul><li><p>In Python 1.4, the class extension mechanism described in <a href="#4">[4]</a> required
- that the first superclass in a list of super-classes must be of the
- extended class type. This may not be convenient if mix-in
- behavior is desired. If a list of base classes starts with a
- standard python class, but includes an extension class, then an
- error was raised. It would be more useful if, when a list of base
- classes contains one or more objects that are not python classes,
- the first such object was used to control the extended class
- definition. To get around this, the <code>ExtensionClass</code> module exports
- a base extension class, <code>Base</code>, that can be used as the first base
- class in a list of base classes to assure that an extension
- subclass is created.</p>
- <p> Python 1.5 allows the class extension even if the first non-class
- object in the list of base classes is not the first object in
- the list. This issue appears to go away in Python 1.5, however,
- the restriction that the first non-class object in a list of
- base classes must be the first in the list may reappear in later
- versions of Python.</p>
-
-
-
- <li><p>Currently, only one base extension class can define any data in
- C. The data layout of subclasses-instances is the same as for the
- base class that defines data in C, except that the data structure
- is extended to hold an instance dictionary. The data structure
- begins with a standard python header, and extension methods expect
- the C instance data to occur immediately after the object header. If
- two or more base classes defined C data, the methods for the
- different base classes would expect their data to be in the same
- location. A solution might be to allocate base class instances and
- store pointers to these instances in the subclass data structure.
- The method binding mechanism would have to be a more complicated
- to make sure that methods were bound to the correct base data
- structure. Alternatively, the signature of C methods could be
- expanded to allow pointers to expected class data to be passed
- in addition to object pointers.</p>
-
-
- <li><p>There is currently no support for sub-classing in C, beyond that
- provided by method chains.</p>
-
-
- <li><p>Rules for mixed-type arithmetic are different for python class
- instances than they are for extension type instances. Python
- classes can define right and left versions of numeric binary
- operators, or they can define a coercion operator for converting
- binary operator operands to a common type. For extension types,
- only the latter, coercion-based, approach is supported. The
- coercion-based approach does not work well for many data types for
- which coercion rules depend on the operator. Because extension
- classes are based on extension types, they are currently limited
- to the coercion-based approach. It should be possible to
- extend the extension class implementation to allow both types of
- mixed-type arithmetic control.</p>
-
-
- <li><p>I considered making extension classes immutable, meaning that
- class attributes could not be set after class creation. I also
- considered making extension subclasses cache inherited
- attributes. Both of these are related and attractive for some
- applications, however, I decided that it would be better to retain
- standard class instance semantics and provide these features as
- options at a later time.</p>
-
-
- <li><p>The extension class module defines new method types to bind C and
- python methods to extension class instances. It would be useful
- for these method objects to provide access to function call
- information, such as the number and names of arguments and the
- number of defaults, by parsing extension function documentation
- strings.</p>
-
- </ul>
-
- <h2>Applications</h2>
- <p> Aside from test and demonstration applications, the extension class
- mechanism has been used to provide an extension-based implementation
- of the persistence mechanism described in <a href="#1">[1]</a>. We have developed
- this further to provide features such as automatic deactivation of
- objects not used after some period of time and to provide more
- efficient persistent-object cache management.</p>
-
- <p> Acquisition has been heavily used in our recent products.
- Synchonized classes have also been used in recent products.</p>
-
-
- <h2>Summary</h2>
- <p> The extension-class mechanism described here provides a way to add
- class services to extension types. It allows:</p>
- <ul><li><p>Sub-classing extension classes in Python,</p>
-
-
- <li><p>Construction of extension class instances by calling extension
- classes,</p>
-
-
- <li><p>Extension classes to provide meta-data, such as unbound methods
- and their documentation string.</p>
-
- </ul>
-
- <p> In addition, the extension class module provides a relatively
- concise example of the use of mechanisms that were added to Python
- to support MESS <a href="#6">[6]</a>, and that were described at the fourth Python
- Workshop <a href="#4">[4]</a>. It is hoped that this will spur research in improved
- and specialized models for class implementation in Python.</p>
-
-
- <p> References</p>
-
- <p> <a name="1">[1]</a> Fulton, J., <a href="http://www.digicool.com/papers/Persistence.html">Providing Persistence for World-Wide-Web Applications</a>
- Proceedings of the 5th Python Workshop.</p>
-
- <p> <a name="2">[2]</a> Page, R. and Cropper, S., <a href="http://www.digicool.com/papers/DocumentTemplate.html">Document Template</a>
- Proceedings of the 5th Python Workshop.</p>
-
- <p> <a name="3">[3]</a> Beaudry, D., <a href="http://www.python.org/workshops/1994-11/BuiltInClasses/BuiltInClasses_1.html">Deriving Built-In Classes in Python</a>
- Proceedings of the First International Python Workshop.</p>
-
- <p> <a name="4">[4]</a> Van Rossum, G., <a href="http://www.python.org/workshops/1996-06/notes/thursday.html">Don Beaudry Hack - MESS</a>
- presented in the Developer's Future Enhancements session of the
- 4th Python Workshop. </p>
-
- <p> <a name="5">[5]</a> Fulton, J., <a href="http://www.digicool.com/jim/MetaType.c">Meta-Type Object</a>
- This is a small proposal, the text of which is contained in a
- sample implementation source file, </p>
-
- <p> <a name="6">[6]</a> Beaudry, D., and Ascher, D., "The Meta-Extension Set",
- http://starship.skyport.net/~da/mess/.
- </p>
-
-
-
-